<!DOCTYPE html>
<html lang="" xml:lang="">
<head>

  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <title>Chapter 8 Advanced Topics | JavaScript for R</title>
  <meta name="description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="generator" content="bookdown 0.20 and GitBook 2.6.7" />

  <meta property="og:title" content="Chapter 8 Advanced Topics | JavaScript for R" />
  <meta property="og:type" content="book" />
  
  
  <meta property="og:description" content="Invite JavaScript into your Data Science workflow." />
  <meta name="github-repo" content="JohnCoene/javascript-for-r" />

  <meta name="twitter:card" content="summary" />
  <meta name="twitter:title" content="Chapter 8 Advanced Topics | JavaScript for R" />
  
  <meta name="twitter:description" content="Invite JavaScript into your Data Science workflow." />
  

<meta name="author" content="John Coene" />


<meta name="date" content="2020-09-04" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black" />
  
  
<link rel="prev" href="the-full-monty.html"/>
<link rel="next" href="linking-widgets.html"/>
<script src="libs/header-attrs/header-attrs.js"></script>
<script src="libs/jquery/jquery.min.js"></script>
<link href="libs/gitbook/css/style.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-table.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-bookdown.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-highlight.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-search.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-fontsettings.css" rel="stylesheet" />
<link href="libs/gitbook/css/plugin-clipboard.css" rel="stylesheet" />









<script src="libs/accessible-code-block/empty-anchor.js"></script>
<script src="libs/htmlwidgets/htmlwidgets.js"></script>
<script src="libs/plotly-binding/plotly.js"></script>
<script src="libs/typedarray/typedarray.min.js"></script>
<link href="libs/crosstalk/css/crosstalk.css" rel="stylesheet" />
<script src="libs/crosstalk/js/crosstalk.min.js"></script>
<link href="libs/plotly-htmlwidgets-css/plotly-htmlwidgets.css" rel="stylesheet" />
<script src="libs/plotly-main/plotly-latest.min.js"></script>
<script src="libs/core-js/shim.min.js"></script>
<script src="libs/react/react.min.js"></script>
<script src="libs/react/react-dom.min.js"></script>
<script src="libs/reactwidget/react-tools.js"></script>
<script src="libs/reactable-binding/reactable.js"></script>
<script src="libs/r2d3-render/r2d3-render.js"></script>
<script src="libs/webcomponents/webcomponents.js"></script>
<script src="libs/r2d3-binding/r2d3.js"></script>
<script src="libs/d3v5/d3.min.js"></script>
<script src="libs/viz/viz.js"></script>
<link href="libs/DiagrammeR-styles/styles.css" rel="stylesheet" />
<script src="libs/grViz-binding/grViz.js"></script>


<style type="text/css">
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
  { counter-reset: source-line 0; }
pre.numberSource code > span
  { position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
  { content: counter(source-line);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {   }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>

<link rel="stylesheet" href="css/style.css" type="text/css" />
<link rel="stylesheet" href="css/toc.css" type="text/css" />
</head>

<body>



  <div class="book without-animation with-summary font-size-2 font-family-1" data-basepath=".">

    <div class="book-summary">
      <nav role="navigation">

<ul class="summary">
<li><a href="./">JavaScript for R</a></li>

<li class="divider"></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html"><i class="fa fa-check"></i>Preface</a>
<ul>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#premise"><i class="fa fa-check"></i>Premise</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#book-structure"><i class="fa fa-check"></i>Book Structure</a></li>
<li class="chapter" data-level="" data-path="index.html"><a href="index.html#acknowledgement"><i class="fa fa-check"></i>Acknowledgement</a></li>
</ul></li>
<li class="part"><span><b>I Basics &amp; Roadmap</b></span></li>
<li class="chapter" data-level="1" data-path="overview.html"><a href="overview.html"><i class="fa fa-check"></i><b>1</b> Overview</a>
<ul>
<li class="chapter" data-level="1.1" data-path="overview.html"><a href="overview.html#rationale"><i class="fa fa-check"></i><b>1.1</b> Rationale</a></li>
<li class="chapter" data-level="1.2" data-path="overview.html"><a href="overview.html#methods"><i class="fa fa-check"></i><b>1.2</b> Methods</a>
<ul>
<li class="chapter" data-level="1.2.1" data-path="overview.html"><a href="overview.html#v8"><i class="fa fa-check"></i><b>1.2.1</b> V8</a></li>
<li class="chapter" data-level="1.2.2" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>1.2.2</b> htmlwidgets</a></li>
<li class="chapter" data-level="1.2.3" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>1.2.3</b> Shiny</a></li>
<li class="chapter" data-level="1.2.4" data-path="overview.html"><a href="overview.html#bubble"><i class="fa fa-check"></i><b>1.2.4</b> bubble</a></li>
</ul></li>
<li class="chapter" data-level="1.3" data-path="overview.html"><a href="overview.html#methods-amiss"><i class="fa fa-check"></i><b>1.3</b> Methods Amiss</a>
<ul>
<li class="chapter" data-level="1.3.1" data-path="overview.html"><a href="overview.html#reactr"><i class="fa fa-check"></i><b>1.3.1</b> reactR</a></li>
<li class="chapter" data-level="1.3.2" data-path="overview.html"><a href="overview.html#r2d3"><i class="fa fa-check"></i><b>1.3.2</b> r2d3</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="2" data-path="prerequisites.html"><a href="prerequisites.html"><i class="fa fa-check"></i><b>2</b> Prerequisites</a>
<ul>
<li class="chapter" data-level="2.1" data-path="prerequisites.html"><a href="prerequisites.html#r-package-development"><i class="fa fa-check"></i><b>2.1</b> R Package Development</a>
<ul>
<li class="chapter" data-level="2.1.1" data-path="prerequisites.html"><a href="prerequisites.html#creating-a-package"><i class="fa fa-check"></i><b>2.1.1</b> Creating a Package</a></li>
<li class="chapter" data-level="2.1.2" data-path="prerequisites.html"><a href="prerequisites.html#metadata"><i class="fa fa-check"></i><b>2.1.2</b> Metadata</a></li>
<li class="chapter" data-level="2.1.3" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>2.1.3</b> R code</a></li>
<li class="chapter" data-level="2.1.4" data-path="prerequisites.html"><a href="prerequisites.html#documentation"><i class="fa fa-check"></i><b>2.1.4</b> Documentation</a></li>
<li class="chapter" data-level="2.1.5" data-path="prerequisites.html"><a href="prerequisites.html#installed-files"><i class="fa fa-check"></i><b>2.1.5</b> Installed files</a></li>
<li class="chapter" data-level="2.1.6" data-path="prerequisites.html"><a href="prerequisites.html#build-load-and-install"><i class="fa fa-check"></i><b>2.1.6</b> Build, load, and install</a></li>
</ul></li>
<li class="chapter" data-level="2.2" data-path="prerequisites.html"><a href="prerequisites.html#json"><i class="fa fa-check"></i><b>2.2</b> JSON</a>
<ul>
<li class="chapter" data-level="2.2.1" data-path="prerequisites.html"><a href="prerequisites.html#serialising"><i class="fa fa-check"></i><b>2.2.1</b> Serialising</a></li>
<li class="chapter" data-level="2.2.2" data-path="prerequisites.html"><a href="prerequisites.html#tabular-data"><i class="fa fa-check"></i><b>2.2.2</b> Tabular data</a></li>
</ul></li>
<li class="chapter" data-level="2.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>2.3</b> JavaScript</a>
<ul>
<li class="chapter" data-level="2.3.1" data-path="prerequisites.html"><a href="prerequisites.html#developer-tools"><i class="fa fa-check"></i><b>2.3.1</b> Developer tools</a></li>
<li class="chapter" data-level="2.3.2" data-path="prerequisites.html"><a href="prerequisites.html#variable-declaration-and-scope"><i class="fa fa-check"></i><b>2.3.2</b> Variable declaration and scope</a></li>
<li class="chapter" data-level="2.3.3" data-path="prerequisites.html"><a href="prerequisites.html#document-object-model"><i class="fa fa-check"></i><b>2.3.3</b> Document object model</a></li>
</ul></li>
<li class="chapter" data-level="2.4" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>2.4</b> Shiny</a>
<ul>
<li class="chapter" data-level="2.4.1" data-path="prerequisites.html"><a href="prerequisites.html#htmltools"><i class="fa fa-check"></i><b>2.4.1</b> Htmltools</a></li>
<li class="chapter" data-level="2.4.2" data-path="prerequisites.html"><a href="prerequisites.html#static-files"><i class="fa fa-check"></i><b>2.4.2</b> Static files</a></li>
<li class="chapter" data-level="2.4.3" data-path="prerequisites.html"><a href="prerequisites.html#dependencies-pros-and-cons"><i class="fa fa-check"></i><b>2.4.3</b> Dependencies Pros and Cons</a></li>
</ul></li>
</ul></li>
<li class="part"><span><b>II Data Visualisation</b></span></li>
<li class="chapter" data-level="3" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html"><i class="fa fa-check"></i><b>3</b> Introduction to Widgets</a>
<ul>
<li class="chapter" data-level="3.1" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#plotly-package"><i class="fa fa-check"></i><b>3.1</b> Plotly package</a></li>
<li class="chapter" data-level="3.2" data-path="introduction-to-widgets.html"><a href="introduction-to-widgets.html#dt-package"><i class="fa fa-check"></i><b>3.2</b> DT package</a></li>
</ul></li>
<li class="chapter" data-level="4" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html"><i class="fa fa-check"></i><b>4</b> Basics of Building Widgets</a>
<ul>
<li class="chapter" data-level="4.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#candidate-libraries"><i class="fa fa-check"></i><b>4.1</b> Candidate Libraries</a>
<ul>
<li class="chapter" data-level="4.1.1" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#plotly.js"><i class="fa fa-check"></i><b>4.1.1</b> Plotly.js</a></li>
<li class="chapter" data-level="4.1.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#highchart.js"><i class="fa fa-check"></i><b>4.1.2</b> Highchart.js</a></li>
<li class="chapter" data-level="4.1.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#chart.js"><i class="fa fa-check"></i><b>4.1.3</b> Chart.js</a></li>
</ul></li>
<li class="chapter" data-level="4.2" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>4.2</b> How it works</a></li>
</ul></li>
<li class="chapter" data-level="5" data-path="your-first-widget.html"><a href="your-first-widget.html"><i class="fa fa-check"></i><b>5</b> Your First Widget</a>
<ul>
<li class="chapter" data-level="5.1" data-path="your-first-widget.html"><a href="your-first-widget.html#the-htmlwidgets-scaffold"><i class="fa fa-check"></i><b>5.1</b> The Htmlwidgets Scaffold</a></li>
<li class="chapter" data-level="5.2" data-path="your-first-widget.html"><a href="your-first-widget.html#the-html-output"><i class="fa fa-check"></i><b>5.2</b> The HTML Output</a></li>
<li class="chapter" data-level="5.3" data-path="your-first-widget.html"><a href="your-first-widget.html#htmlwidgets-javascript-files"><i class="fa fa-check"></i><b>5.3</b> Htmlwidgets JavaScript Files</a></li>
</ul></li>
<li class="chapter" data-level="6" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html"><i class="fa fa-check"></i><b>6</b> A Realistic Widget</a>
<ul>
<li class="chapter" data-level="6.1" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-dependencies"><i class="fa fa-check"></i><b>6.1</b> Peity.js Dependencies</a></li>
<li class="chapter" data-level="6.2" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-implementation"><i class="fa fa-check"></i><b>6.2</b> Peity.js Implementation</a></li>
<li class="chapter" data-level="6.3" data-path="a-realistic-widget.html"><a href="a-realistic-widget.html#peity.js-html-element"><i class="fa fa-check"></i><b>6.3</b> Peity.js HTML Element</a></li>
</ul></li>
<li class="chapter" data-level="7" data-path="the-full-monty.html"><a href="the-full-monty.html"><i class="fa fa-check"></i><b>7</b> The Full Monty</a>
<ul>
<li class="chapter" data-level="7.1" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-dependencies"><i class="fa fa-check"></i><b>7.1</b> Gio.js Dependencies</a></li>
<li class="chapter" data-level="7.2" data-path="the-full-monty.html"><a href="the-full-monty.html#gio.js-javascript"><i class="fa fa-check"></i><b>7.2</b> Gio.js JavaScript</a></li>
<li class="chapter" data-level="7.3" data-path="the-full-monty.html"><a href="the-full-monty.html#working-with-data"><i class="fa fa-check"></i><b>7.3</b> Working with Data</a></li>
<li class="chapter" data-level="7.4" data-path="the-full-monty.html"><a href="the-full-monty.html#transforming-data"><i class="fa fa-check"></i><b>7.4</b> Transforming Data</a>
<ul>
<li class="chapter" data-level="7.4.1" data-path="the-full-monty.html"><a href="the-full-monty.html#using-javascript"><i class="fa fa-check"></i><b>7.4.1</b> Using JavaScript</a></li>
<li class="chapter" data-level="7.4.2" data-path="the-full-monty.html"><a href="the-full-monty.html#using-r"><i class="fa fa-check"></i><b>7.4.2</b> Using R</a></li>
<li class="chapter" data-level="7.4.3" data-path="the-full-monty.html"><a href="the-full-monty.html#pros-cons"><i class="fa fa-check"></i><b>7.4.3</b> Pros &amp; Cons</a></li>
</ul></li>
<li class="chapter" data-level="7.5" data-path="the-full-monty.html"><a href="the-full-monty.html#on-print-method"><i class="fa fa-check"></i><b>7.5</b> On Print Method</a></li>
</ul></li>
<li class="chapter" data-level="8" data-path="advanced-topics.html"><a href="advanced-topics.html"><i class="fa fa-check"></i><b>8</b> Advanced Topics</a>
<ul>
<li class="chapter" data-level="8.1" data-path="advanced-topics.html"><a href="advanced-topics.html#shared-variables"><i class="fa fa-check"></i><b>8.1</b> Shared Variables</a>
<ul>
<li class="chapter" data-level="8.1.1" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing"><i class="fa fa-check"></i><b>8.1.1</b> Sizing</a></li>
<li class="chapter" data-level="8.1.2" data-path="advanced-topics.html"><a href="advanced-topics.html#sizing-policy"><i class="fa fa-check"></i><b>8.1.2</b> Sizing Policy</a></li>
</ul></li>
<li class="chapter" data-level="8.2" data-path="advanced-topics.html"><a href="advanced-topics.html#resizing"><i class="fa fa-check"></i><b>8.2</b> Resizing</a></li>
<li class="chapter" data-level="8.3" data-path="advanced-topics.html"><a href="advanced-topics.html#pre-render-hooks-security"><i class="fa fa-check"></i><b>8.3</b> Pre Render Hooks &amp; Security</a></li>
<li class="chapter" data-level="8.4" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>8.4</b> JavaScript Code</a></li>
<li class="chapter" data-level="8.5" data-path="advanced-topics.html"><a href="advanced-topics.html#prepend-append-content"><i class="fa fa-check"></i><b>8.5</b> Prepend &amp; Append Content</a></li>
<li class="chapter" data-level="8.6" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>8.6</b> Dependencies</a></li>
<li class="chapter" data-level="8.7" data-path="advanced-topics.html"><a href="advanced-topics.html#compatibility"><i class="fa fa-check"></i><b>8.7</b> Compatibility</a></li>
<li class="chapter" data-level="8.8" data-path="advanced-topics.html"><a href="advanced-topics.html#unit-tests"><i class="fa fa-check"></i><b>8.8</b> Unit Tests</a></li>
<li class="chapter" data-level="8.9" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>8.9</b> Performances</a></li>
</ul></li>
<li class="chapter" data-level="9" data-path="linking-widgets.html"><a href="linking-widgets.html"><i class="fa fa-check"></i><b>9</b> Linking Widgets</a>
<ul>
<li class="chapter" data-level="9.1" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-examples"><i class="fa fa-check"></i><b>9.1</b> Crosstalk examples</a></li>
<li class="chapter" data-level="9.2" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-requirements"><i class="fa fa-check"></i><b>9.2</b> Crosstalk requirements</a></li>
<li class="chapter" data-level="9.3" data-path="basics-of-building-widgets.html"><a href="basics-of-building-widgets.html#how-it-works"><i class="fa fa-check"></i><b>9.3</b> How it works</a></li>
<li class="chapter" data-level="9.4" data-path="linking-widgets.html"><a href="linking-widgets.html#crosstalk-with-gio"><i class="fa fa-check"></i><b>9.4</b> Crosstalk with gio</a></li>
<li class="chapter" data-level="9.5" data-path="linking-widgets.html"><a href="linking-widgets.html#adapt-the-r-code"><i class="fa fa-check"></i><b>9.5</b> Adapt the R code</a></li>
<li class="chapter" data-level="9.6" data-path="linking-widgets.html"><a href="linking-widgets.html#change-the-javascript-code"><i class="fa fa-check"></i><b>9.6</b> Change the JavaScript code</a>
<ul>
<li class="chapter" data-level="9.6.1" data-path="linking-widgets.html"><a href="linking-widgets.html#send-selected-keys"><i class="fa fa-check"></i><b>9.6.1</b> Send selected keys</a></li>
<li class="chapter" data-level="9.6.2" data-path="linking-widgets.html"><a href="linking-widgets.html#set-selected-keys"><i class="fa fa-check"></i><b>9.6.2</b> Set selected keys</a></li>
<li class="chapter" data-level="9.6.3" data-path="linking-widgets.html"><a href="linking-widgets.html#recap-javascript-code"><i class="fa fa-check"></i><b>9.6.3</b> Recap JavaScript code</a></li>
</ul></li>
<li class="chapter" data-level="9.7" data-path="linking-widgets.html"><a href="linking-widgets.html#using-crosstalk-with-gio"><i class="fa fa-check"></i><b>9.7</b> Using crosstalk with gio</a></li>
</ul></li>
<li class="chapter" data-level="10" data-path="final-revisions.html"><a href="final-revisions.html"><i class="fa fa-check"></i><b>10</b> Final Revisions</a>
<ul>
<li class="chapter" data-level="10.1" data-path="final-revisions.html"><a href="final-revisions.html#htmlwidgets-data"><i class="fa fa-check"></i><b>10.1</b> Htmlwidgets &amp; Data</a></li>
<li class="chapter" data-level="10.2" data-path="final-revisions.html"><a href="final-revisions.html#plethora-of-options"><i class="fa fa-check"></i><b>10.2</b> Plethora of Options</a></li>
<li class="chapter" data-level="10.3" data-path="final-revisions.html"><a href="final-revisions.html#interface-design"><i class="fa fa-check"></i><b>10.3</b> Interface Design</a></li>
</ul></li>
<li class="chapter" data-level="11" data-path="excercise-ploty.html"><a href="excercise-ploty.html"><i class="fa fa-check"></i><b>11</b> Excercise - Ploty</a>
<ul>
<li class="chapter" data-level="11.1" data-path="excercise-ploty.html"><a href="excercise-ploty.html#discover-plotly"><i class="fa fa-check"></i><b>11.1</b> Discover Plotly</a></li>
<li class="chapter" data-level="11.2" data-path="excercise-ploty.html"><a href="excercise-ploty.html#basics-of-plotly"><i class="fa fa-check"></i><b>11.2</b> Basics of Plotly</a></li>
<li class="chapter" data-level="11.3" data-path="excercise-ploty.html"><a href="excercise-ploty.html#plotly.js-to-r"><i class="fa fa-check"></i><b>11.3</b> Plotly.js to R</a></li>
<li class="chapter" data-level="11.4" data-path="excercise-ploty.html"><a href="excercise-ploty.html#r-to-plotly.js"><i class="fa fa-check"></i><b>11.4</b> R to Plotly.js</a></li>
<li class="chapter" data-level="11.5" data-path="excercise-ploty.html"><a href="excercise-ploty.html#size-resize-plotly.js"><i class="fa fa-check"></i><b>11.5</b> Size &amp; Resize Plotly.js</a></li>
<li class="chapter" data-level="11.6" data-path="excercise-ploty.html"><a href="excercise-ploty.html#performance-security-with-plotly.js"><i class="fa fa-check"></i><b>11.6</b> Performance &amp; Security with Plotly.js</a></li>
</ul></li>
<li class="part"><span><b>III Web Development with Shiny</b></span></li>
<li class="chapter" data-level="12" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html"><i class="fa fa-check"></i><b>12</b> Introduction to Shiny</a>
<ul>
<li class="chapter" data-level="12.1" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#websocket-shiny"><i class="fa fa-check"></i><b>12.1</b> Websocket &amp; Shiny</a></li>
<li class="chapter" data-level="12.2" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-an-example"><i class="fa fa-check"></i><b>12.2</b> Alerts, An Example</a></li>
<li class="chapter" data-level="12.3" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-r-to-js"><i class="fa fa-check"></i><b>12.3</b> From R to JavaScript</a></li>
<li class="chapter" data-level="12.4" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-js-to-r"><i class="fa fa-check"></i><b>12.4</b> From JavaScript to R</a></li>
<li class="chapter" data-level="12.5" data-path="introduction-to-shiny.html"><a href="introduction-to-shiny.html#alerts-deserialise"><i class="fa fa-check"></i><b>12.5</b> Deserialise</a></li>
</ul></li>
<li class="chapter" data-level="13" data-path="a-complete-integration.html"><a href="a-complete-integration.html"><i class="fa fa-check"></i><b>13</b> A Complete Integration</a>
<ul>
<li class="chapter" data-level="13.1" data-path="a-complete-integration.html"><a href="a-complete-integration.html#serialisation"><i class="fa fa-check"></i><b>13.1</b> Serialisation</a></li>
<li class="chapter" data-level="13.2" data-path="a-complete-integration.html"><a href="a-complete-integration.html#events-callbacks"><i class="fa fa-check"></i><b>13.2</b> Events &amp; Callbacks</a></li>
<li class="chapter" data-level="13.3" data-path="a-complete-integration.html"><a href="a-complete-integration.html#as-a-package"><i class="fa fa-check"></i><b>13.3</b> As a Package</a>
<ul>
<li class="chapter" data-level="13.3.1" data-path="advanced-topics.html"><a href="advanced-topics.html#dependencies"><i class="fa fa-check"></i><b>13.3.1</b> Dependencies</a></li>
<li class="chapter" data-level="13.3.2" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>13.3.2</b> R Code</a></li>
<li class="chapter" data-level="13.3.3" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>13.3.3</b> JavaScript Code</a></li>
<li class="chapter" data-level="13.3.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>13.3.4</b> Input Handler</a></li>
<li class="chapter" data-level="13.3.5" data-path="a-complete-integration.html"><a href="a-complete-integration.html#wrapping-up"><i class="fa fa-check"></i><b>13.3.5</b> Wrapping up</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="14" data-path="tips-tricks.html"><a href="tips-tricks.html"><i class="fa fa-check"></i><b>14</b> Tips &amp; Tricks</a>
<ul>
<li class="chapter" data-level="14.1" data-path="tips-tricks.html"><a href="tips-tricks.html#shiny-events"><i class="fa fa-check"></i><b>14.1</b> Shiny Events</a></li>
<li class="chapter" data-level="14.2" data-path="tips-tricks.html"><a href="tips-tricks.html#table-buttons"><i class="fa fa-check"></i><b>14.2</b> Table Buttons</a></li>
<li class="chapter" data-level="14.3" data-path="tips-tricks.html"><a href="tips-tricks.html#jquery---toggle"><i class="fa fa-check"></i><b>14.3</b> jQuery - Toggle</a></li>
</ul></li>
<li class="chapter" data-level="15" data-path="custom-outputs.html"><a href="custom-outputs.html"><i class="fa fa-check"></i><b>15</b> Custom Outputs</a>
<ul>
<li class="chapter" data-level="15.1" data-path="custom-outputs.html"><a href="custom-outputs.html#custom-outputs-inner-workings"><i class="fa fa-check"></i><b>15.1</b> Custom Outputs Inner-workings</a></li>
<li class="chapter" data-level="15.2" data-path="custom-outputs.html"><a href="custom-outputs.html#setup-custom-output"><i class="fa fa-check"></i><b>15.2</b> Setup Custom Output</a></li>
<li class="chapter" data-level="15.3" data-path="custom-outputs.html"><a href="custom-outputs.html#output-r-function"><i class="fa fa-check"></i><b>15.3</b> Output R Function</a></li>
<li class="chapter" data-level="15.4" data-path="custom-outputs.html"><a href="custom-outputs.html#generate-output-html"><i class="fa fa-check"></i><b>15.4</b> Generate Output HTML</a></li>
<li class="chapter" data-level="15.5" data-path="custom-outputs.html"><a href="custom-outputs.html#output-renderer"><i class="fa fa-check"></i><b>15.5</b> Output Renderer</a></li>
<li class="chapter" data-level="15.6" data-path="custom-outputs.html"><a href="custom-outputs.html#javascript-output-binding"><i class="fa fa-check"></i><b>15.6</b> JavaScript Output Binding</a>
<ul>
<li class="chapter" data-level="15.6.1" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-title"><i class="fa fa-check"></i><b>15.6.1</b> Boxxy title</a></li>
<li class="chapter" data-level="15.6.2" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-value"><i class="fa fa-check"></i><b>15.6.2</b> Boxxy value</a></li>
<li class="chapter" data-level="15.6.3" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-background-color"><i class="fa fa-check"></i><b>15.6.3</b> Boxxy Background Color</a></li>
<li class="chapter" data-level="15.6.4" data-path="custom-outputs.html"><a href="custom-outputs.html#register-the-output-binding"><i class="fa fa-check"></i><b>15.6.4</b> Register the Output Binding</a></li>
</ul></li>
<li class="chapter" data-level="15.7" data-path="custom-outputs.html"><a href="custom-outputs.html#boxxy-usage"><i class="fa fa-check"></i><b>15.7</b> Boxxy Usage</a></li>
<li class="chapter" data-level="15.8" data-path="custom-outputs.html"><a href="custom-outputs.html#injecting-dependencies"><i class="fa fa-check"></i><b>15.8</b> Injecting Dependencies</a></li>
<li class="chapter" data-level="15.9" data-path="custom-outputs.html"><a href="custom-outputs.html#preprocessing-custom-outputs"><i class="fa fa-check"></i><b>15.9</b> Preprocessing Custom Outputs</a></li>
</ul></li>
<li class="chapter" data-level="16" data-path="custom-inputs.html"><a href="custom-inputs.html"><i class="fa fa-check"></i><b>16</b> Custom Inputs</a>
<ul>
<li class="chapter" data-level="16.1" data-path="custom-inputs.html"><a href="custom-inputs.html#setup-custom-input"><i class="fa fa-check"></i><b>16.1</b> Setup Custom Input</a></li>
<li class="chapter" data-level="16.2" data-path="custom-inputs.html"><a href="custom-inputs.html#switch-input-html-style"><i class="fa fa-check"></i><b>16.2</b> Switch Input HTML &amp; Style</a></li>
<li class="chapter" data-level="16.3" data-path="custom-inputs.html"><a href="custom-inputs.html#generate-input-html"><i class="fa fa-check"></i><b>16.3</b> Generate Input HTML</a></li>
<li class="chapter" data-level="16.4" data-path="custom-inputs.html"><a href="custom-inputs.html#javascript-input-binding"><i class="fa fa-check"></i><b>16.4</b> JavaScript Input Binding</a>
<ul>
<li class="chapter" data-level="16.4.1" data-path="custom-inputs.html"><a href="custom-inputs.html#find-inputs"><i class="fa fa-check"></i><b>16.4.1</b> Find Inputs</a></li>
<li class="chapter" data-level="16.4.2" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-id"><i class="fa fa-check"></i><b>16.4.2</b> Get Input Id</a></li>
<li class="chapter" data-level="16.4.3" data-path="custom-inputs.html"><a href="custom-inputs.html#get-input-value"><i class="fa fa-check"></i><b>16.4.3</b> Get Input Value</a></li>
<li class="chapter" data-level="16.4.4" data-path="custom-inputs.html"><a href="custom-inputs.html#set-input-value"><i class="fa fa-check"></i><b>16.4.4</b> Set Input Value</a></li>
<li class="chapter" data-level="16.4.5" data-path="custom-inputs.html"><a href="custom-inputs.html#receive-input-messages"><i class="fa fa-check"></i><b>16.4.5</b> Receive Input Messages</a></li>
<li class="chapter" data-level="16.4.6" data-path="custom-inputs.html"><a href="custom-inputs.html#subscribe-unsubscribe-inputs"><i class="fa fa-check"></i><b>16.4.6</b> Subscribe &amp; Unsubscribe Inputs</a></li>
<li class="chapter" data-level="16.4.7" data-path="custom-inputs.html"><a href="custom-inputs.html#input-rate-policy"><i class="fa fa-check"></i><b>16.4.7</b> Input Rate Policy</a></li>
<li class="chapter" data-level="16.4.8" data-path="custom-inputs.html"><a href="custom-inputs.html#registering-the-input"><i class="fa fa-check"></i><b>16.4.8</b> Registering the Input</a></li>
</ul></li>
<li class="chapter" data-level="16.5" data-path="custom-inputs.html"><a href="custom-inputs.html#update-input"><i class="fa fa-check"></i><b>16.5</b> Update Input</a></li>
<li class="chapter" data-level="16.6" data-path="custom-inputs.html"><a href="custom-inputs.html#exercise"><i class="fa fa-check"></i><b>16.6</b> Exercise</a></li>
</ul></li>
<li class="chapter" data-level="17" data-path="cookies.html"><a href="cookies.html"><i class="fa fa-check"></i><b>17</b> Cookies</a>
<ul>
<li class="chapter" data-level="17.1" data-path="cookies.html"><a href="cookies.html#discover-js-cookie"><i class="fa fa-check"></i><b>17.1</b> Discover js-cookie</a></li>
<li class="chapter" data-level="17.2" data-path="cookies.html"><a href="cookies.html#setup-cookies-project"><i class="fa fa-check"></i><b>17.2</b> Setup Cookies Project</a></li>
<li class="chapter" data-level="17.3" data-path="cookies.html"><a href="cookies.html#javascript-cookies"><i class="fa fa-check"></i><b>17.3</b> JavaScript Cookies</a></li>
<li class="chapter" data-level="17.4" data-path="cookies.html"><a href="cookies.html#r-code-for-cookies"><i class="fa fa-check"></i><b>17.4</b> R Code for Cookies</a></li>
</ul></li>
<li class="chapter" data-level="18" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html"><i class="fa fa-check"></i><b>18</b> Widgets with Shiny</a>
<ul>
<li class="chapter" data-level="18.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#widgets-to-r"><i class="fa fa-check"></i><b>18.1</b> Widgets to R</a></li>
<li class="chapter" data-level="18.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#input-handlers-for-widgets"><i class="fa fa-check"></i><b>18.2</b> Input Handlers for Widgets</a></li>
<li class="chapter" data-level="18.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#r-to-widgets"><i class="fa fa-check"></i><b>18.3</b> R to Widgets</a>
<ul>
<li class="chapter" data-level="18.3.1" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#send-data-from-widgets"><i class="fa fa-check"></i><b>18.3.1</b> Send Data from Widgets</a></li>
<li class="chapter" data-level="18.3.2" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#retrieve-widget-instance"><i class="fa fa-check"></i><b>18.3.2</b> Retrieve Widget Instance</a></li>
<li class="chapter" data-level="18.3.3" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#handle-data"><i class="fa fa-check"></i><b>18.3.3</b> Handle Data</a></li>
</ul></li>
<li class="chapter" data-level="18.4" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#proxy-function"><i class="fa fa-check"></i><b>18.4</b> Proxy Function</a></li>
<li class="chapter" data-level="18.5" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#clear-data"><i class="fa fa-check"></i><b>18.5</b> Clear Data</a></li>
<li class="chapter" data-level="18.6" data-path="widgets-with-shiny.html"><a href="widgets-with-shiny.html#update-the-widget"><i class="fa fa-check"></i><b>18.6</b> Update the Widget</a></li>
</ul></li>
<li class="part"><span><b>IV Interactive Documents</b></span></li>
<li class="chapter" data-level="19" data-path="introduction-to-rmarkdown.html"><a href="introduction-to-rmarkdown.html"><i class="fa fa-check"></i><b>19</b> Introduction to Rmarkdown</a></li>
<li class="part"><span><b>V JavaScript for Computations</b></span></li>
<li class="chapter" data-level="20" data-path="the-v8-engine.html"><a href="the-v8-engine.html"><i class="fa fa-check"></i><b>20</b> The V8 Engine</a>
<ul>
<li class="chapter" data-level="20.1" data-path="the-v8-engine.html"><a href="the-v8-engine.html#installation"><i class="fa fa-check"></i><b>20.1</b> Installation</a></li>
<li class="chapter" data-level="20.2" data-path="the-v8-engine.html"><a href="the-v8-engine.html#basics"><i class="fa fa-check"></i><b>20.2</b> Basics</a></li>
<li class="chapter" data-level="20.3" data-path="the-v8-engine.html"><a href="the-v8-engine.html#external-libraries"><i class="fa fa-check"></i><b>20.3</b> External Libraries</a></li>
<li class="chapter" data-level="20.4" data-path="the-v8-engine.html"><a href="the-v8-engine.html#with-npm"><i class="fa fa-check"></i><b>20.4</b> With Npm</a></li>
<li class="chapter" data-level="20.5" data-path="the-v8-engine.html"><a href="the-v8-engine.html#use-in-packages"><i class="fa fa-check"></i><b>20.5</b> Use in Packages</a></li>
</ul></li>
<li class="chapter" data-level="21" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html"><i class="fa fa-check"></i><b>21</b> Exercise - Machine Learning</a>
<ul>
<li class="chapter" data-level="21.1" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#dependency"><i class="fa fa-check"></i><b>21.1</b> Dependency</a></li>
<li class="chapter" data-level="21.2" data-path="exercise-machine-learning.html"><a href="exercise-machine-learning.html#simple-regression"><i class="fa fa-check"></i><b>21.2</b> Simple Regression</a></li>
</ul></li>
<li class="part"><span><b>VI Examples</b></span></li>
<li class="chapter" data-level="22" data-path="image-classifier.html"><a href="image-classifier.html"><i class="fa fa-check"></i><b>22</b> Image Classifier</a>
<ul>
<li class="chapter" data-level="22.1" data-path="image-classifier.html"><a href="image-classifier.html#discover"><i class="fa fa-check"></i><b>22.1</b> Discover</a></li>
<li class="chapter" data-level="22.2" data-path="image-classifier.html"><a href="image-classifier.html#setup"><i class="fa fa-check"></i><b>22.2</b> Setup</a></li>
<li class="chapter" data-level="22.3" data-path="prerequisites.html"><a href="prerequisites.html#javascript"><i class="fa fa-check"></i><b>22.3</b> JavaScript</a></li>
<li class="chapter" data-level="22.4" data-path="a-complete-integration.html"><a href="a-complete-integration.html#input-handler"><i class="fa fa-check"></i><b>22.4</b> Input Handler</a></li>
</ul></li>
<li class="chapter" data-level="23" data-path="progress-bar.html"><a href="progress-bar.html"><i class="fa fa-check"></i><b>23</b> Progress Bar</a>
<ul>
<li class="chapter" data-level="23.1" data-path="prerequisites.html"><a href="prerequisites.html#r-code"><i class="fa fa-check"></i><b>23.1</b> R code</a></li>
<li class="chapter" data-level="23.2" data-path="advanced-topics.html"><a href="advanced-topics.html#javascript-code"><i class="fa fa-check"></i><b>23.2</b> JavaScript code</a></li>
<li class="chapter" data-level="23.3" data-path="progress-bar.html"><a href="progress-bar.html#events"><i class="fa fa-check"></i><b>23.3</b> Events</a></li>
</ul></li>
<li class="part"><span><b>VII Closing Remarks</b></span></li>
<li class="chapter" data-level="24" data-path="conclusion.html"><a href="conclusion.html"><i class="fa fa-check"></i><b>24</b> Conclusion</a>
<ul>
<li class="chapter" data-level="24.1" data-path="advanced-topics.html"><a href="advanced-topics.html#performances"><i class="fa fa-check"></i><b>24.1</b> Performances</a></li>
<li class="chapter" data-level="24.2" data-path="conclusion.html"><a href="conclusion.html#road-ahead"><i class="fa fa-check"></i><b>24.2</b> Road ahead</a>
<ul>
<li class="chapter" data-level="24.2.1" data-path="conclusion.html"><a href="conclusion.html#computation"><i class="fa fa-check"></i><b>24.2.1</b> Computation</a></li>
<li class="chapter" data-level="24.2.2" data-path="overview.html"><a href="overview.html#shiny"><i class="fa fa-check"></i><b>24.2.2</b> Shiny</a></li>
<li class="chapter" data-level="24.2.3" data-path="overview.html"><a href="overview.html#htmlwidgets"><i class="fa fa-check"></i><b>24.2.3</b> htmlwidgets</a></li>
</ul></li>
</ul></li>
<li class="chapter" data-level="" data-path="references.html"><a href="references.html"><i class="fa fa-check"></i>References</a></li>
</ul>

      </nav>
    </div>

    <div class="book-body">
      <div class="body-inner">
        <div class="book-header" role="navigation">
          <h1>
            <i class="fa fa-circle-o-notch fa-spin"></i><a href="./">JavaScript for R</a>
          </h1>
        </div>

        <div class="page-wrapper" tabindex="-1" role="main">
          <div class="page-inner">

            <section class="normal" id="section-">
<div id="advanced-topics" class="section level1" number="8">
<h1><span class="header-section-number">Chapter 8</span> Advanced Topics</h1>
<p>In the previous chapter we put together an interesting, fully functioning widget but it lacks polish and does not use all the features htmlwidgets provides, this chapter explores those. We look into handling the size of widgets to ensure they are responsive as well as discuss potential security concerns and how to address them. Finally we show how to pass JavaScript code from R to JavaScript and how to add HTML content before and after the widget.</p>
<div id="shared-variables" class="section level2" number="8.1">
<h2><span class="header-section-number">8.1</span> Shared Variables</h2>
<p>Up until now the topic of shared variables had been omitted as it was not relevant, however, it will be from here onwards. Indeed we are about to discover how to further manipulate the widget; changing the data, resizing, and more. This will generally involve the JavaScript instance of the visualisation, the object named <code>controller</code> in the gio package, which, being defined in the <code>renderValue</code> function, is not accessible outside of it. To make it accessible outside of <code>renderValue</code> requires a tiny but consequential change without which resizing the widget will not be doable for instance.</p>
<p>The <code>controller</code> variable has to be declared outside of the <code>renderValue</code> function, inside the <code>factory</code>. This was in fact indicated from the onset by the following comment: <code>// TODO: define shared variables for this instance</code> (generated by <code>htmlwidgets::scaffoldWidget</code>). Any variable declared as shown below will be accessible by all functions declared in the <code>factory</code>; <code>renderValue</code>, but also <code>resize</code> and others yet to be added.</p>
<div class="sourceCode" id="cb161"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb161-1"><a href="advanced-topics.html#cb161-1"></a>HTMLWidgets<span class="op">.</span><span class="fu">widget</span>({</span>
<span id="cb161-2"><a href="advanced-topics.html#cb161-2"></a></span>
<span id="cb161-3"><a href="advanced-topics.html#cb161-3"></a>  <span class="dt">name</span><span class="op">:</span> <span class="st">&#39;gio&#39;</span><span class="op">,</span></span>
<span id="cb161-4"><a href="advanced-topics.html#cb161-4"></a></span>
<span id="cb161-5"><a href="advanced-topics.html#cb161-5"></a>  <span class="dt">type</span><span class="op">:</span> <span class="st">&#39;output&#39;</span><span class="op">,</span></span>
<span id="cb161-6"><a href="advanced-topics.html#cb161-6"></a></span>
<span id="cb161-7"><a href="advanced-topics.html#cb161-7"></a>  <span class="dt">factory</span><span class="op">:</span> <span class="kw">function</span>(el<span class="op">,</span> width<span class="op">,</span> height) {</span>
<span id="cb161-8"><a href="advanced-topics.html#cb161-8"></a></span>
<span id="cb161-9"><a href="advanced-topics.html#cb161-9"></a>    <span class="co">// </span><span class="al">TODO</span><span class="co">: define shared variables for this instance</span></span>
<span id="cb161-10"><a href="advanced-topics.html#cb161-10"></a>    <span class="kw">var</span> controller<span class="op">;</span></span>
<span id="cb161-11"><a href="advanced-topics.html#cb161-11"></a></span>
<span id="cb161-12"><a href="advanced-topics.html#cb161-12"></a>    <span class="cf">return</span> {</span>
<span id="cb161-13"><a href="advanced-topics.html#cb161-13"></a></span>
<span id="cb161-14"><a href="advanced-topics.html#cb161-14"></a>      <span class="dt">renderValue</span><span class="op">:</span> <span class="kw">function</span>(x) {</span>
<span id="cb161-15"><a href="advanced-topics.html#cb161-15"></a></span>
<span id="cb161-16"><a href="advanced-topics.html#cb161-16"></a>        controller <span class="op">=</span> <span class="kw">new</span> GIO<span class="op">.</span><span class="fu">Controller</span>(el)<span class="op">;</span> <span class="co">// declared outside</span></span>
<span id="cb161-17"><a href="advanced-topics.html#cb161-17"></a>        </span>
<span id="cb161-18"><a href="advanced-topics.html#cb161-18"></a>        <span class="co">// add data</span></span>
<span id="cb161-19"><a href="advanced-topics.html#cb161-19"></a>        controller<span class="op">.</span><span class="fu">addData</span>(x<span class="op">.</span><span class="at">data</span>)<span class="op">;</span></span>
<span id="cb161-20"><a href="advanced-topics.html#cb161-20"></a></span>
<span id="cb161-21"><a href="advanced-topics.html#cb161-21"></a>        <span class="co">// define style</span></span>
<span id="cb161-22"><a href="advanced-topics.html#cb161-22"></a>        controller<span class="op">.</span><span class="fu">setStyle</span>(x<span class="op">.</span><span class="at">style</span>)<span class="op">;</span></span>
<span id="cb161-23"><a href="advanced-topics.html#cb161-23"></a></span>
<span id="cb161-24"><a href="advanced-topics.html#cb161-24"></a>        <span class="co">// render</span></span>
<span id="cb161-25"><a href="advanced-topics.html#cb161-25"></a>        controller<span class="op">.</span><span class="fu">init</span>()<span class="op">;</span></span>
<span id="cb161-26"><a href="advanced-topics.html#cb161-26"></a></span>
<span id="cb161-27"><a href="advanced-topics.html#cb161-27"></a>      }<span class="op">,</span></span>
<span id="cb161-28"><a href="advanced-topics.html#cb161-28"></a></span>
<span id="cb161-29"><a href="advanced-topics.html#cb161-29"></a>      <span class="dt">resize</span><span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) {</span>
<span id="cb161-30"><a href="advanced-topics.html#cb161-30"></a></span>
<span id="cb161-31"><a href="advanced-topics.html#cb161-31"></a>        <span class="co">// </span><span class="al">TODO</span><span class="co">: code to re-render the widget with a new size</span></span>
<span id="cb161-32"><a href="advanced-topics.html#cb161-32"></a></span>
<span id="cb161-33"><a href="advanced-topics.html#cb161-33"></a>      }</span>
<span id="cb161-34"><a href="advanced-topics.html#cb161-34"></a></span>
<span id="cb161-35"><a href="advanced-topics.html#cb161-35"></a>    }<span class="op">;</span></span>
<span id="cb161-36"><a href="advanced-topics.html#cb161-36"></a>  }</span>
<span id="cb161-37"><a href="advanced-topics.html#cb161-37"></a>})<span class="op">;</span></span></code></pre></div>
<div id="sizing" class="section level3" number="8.1.1">
<h3><span class="header-section-number">8.1.1</span> Sizing</h3>
<p>The <code>gio</code> function of the package we developed in the previous chapter has arguments to specify the dimensions of the visualisation (width and height). However, think how rarely (if ever) one specifies these parameters when using plotly, highcharter or leaflet. Indeed HTML visualisations should be responsive and fit the container they are placed in—not to be confused though, these are two different things. This enables creating visualisations that look great on large desktop screens as well as the smaller mobile phones or iPad screens. Pre-defining the dimensions of the visualisation (e.g.: <code>400px</code>), breaks all responsiveness as the width is no longer relative to its container. Using a relative width like <code>100%</code> ensures the visualisation always fits in the container edge to edge and enables responsiveness.</p>
<div class="sourceCode" id="cb162"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb162-1"><a href="advanced-topics.html#cb162-1"></a>arcs &lt;-<span class="st"> </span>jsonlite<span class="op">::</span><span class="kw">fromJSON</span>(</span>
<span id="cb162-2"><a href="advanced-topics.html#cb162-2"></a>  <span class="st">&#39;[</span></span>
<span id="cb162-3"><a href="advanced-topics.html#cb162-3"></a><span class="st">    {</span></span>
<span id="cb162-4"><a href="advanced-topics.html#cb162-4"></a><span class="st">      &quot;e&quot;: &quot;CN&quot;,</span></span>
<span id="cb162-5"><a href="advanced-topics.html#cb162-5"></a><span class="st">      &quot;i&quot;: &quot;US&quot;,</span></span>
<span id="cb162-6"><a href="advanced-topics.html#cb162-6"></a><span class="st">      &quot;v&quot;: 3300000</span></span>
<span id="cb162-7"><a href="advanced-topics.html#cb162-7"></a><span class="st">    },</span></span>
<span id="cb162-8"><a href="advanced-topics.html#cb162-8"></a><span class="st">    {</span></span>
<span id="cb162-9"><a href="advanced-topics.html#cb162-9"></a><span class="st">      &quot;e&quot;: &quot;CN&quot;,</span></span>
<span id="cb162-10"><a href="advanced-topics.html#cb162-10"></a><span class="st">      &quot;i&quot;: &quot;RU&quot;,</span></span>
<span id="cb162-11"><a href="advanced-topics.html#cb162-11"></a><span class="st">      &quot;v&quot;: 10000</span></span>
<span id="cb162-12"><a href="advanced-topics.html#cb162-12"></a><span class="st">    }</span></span>
<span id="cb162-13"><a href="advanced-topics.html#cb162-13"></a><span class="st">  ]&#39;</span></span>
<span id="cb162-14"><a href="advanced-topics.html#cb162-14"></a>)</span>
<span id="cb162-15"><a href="advanced-topics.html#cb162-15"></a></span>
<span id="cb162-16"><a href="advanced-topics.html#cb162-16"></a><span class="kw">gio</span>(arcs)</span></code></pre></div>
<div class="figure">
<img src="images/gio-size-issue.png" alt="" />
<p class="caption">Gio with no sizing management</p>
</div>
<p>When this is not specified htmlwidgets sets the width of the visualisation to 400 pixels.</p>
<div class="sourceCode" id="cb163"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb163-1"><a href="advanced-topics.html#cb163-1"></a><span class="kw">gio</span>(arcs, <span class="dt">width =</span> <span class="dv">500</span>) <span class="co"># 500 pixels wide</span></span>
<span id="cb163-2"><a href="advanced-topics.html#cb163-2"></a><span class="kw">gio</span>(arcs, <span class="dt">width =</span> <span class="st">&quot;100%&quot;</span>) <span class="co"># fits width</span></span></code></pre></div>
<p>These options are destined for the user of the package, the next section details how the developer can define default sizing behaviour.</p>
</div>
<div id="sizing-policy" class="section level3" number="8.1.2">
<h3><span class="header-section-number">8.1.2</span> Sizing Policy</h3>
<p>One can specify a sizing policy when creating the widget, the sizing policy will dictate default dimensions and padding given different contexts:</p>
<ul>
<li>Global defaults</li>
<li>RStudio viewer</li>
<li>Web browser</li>
<li>R markdown</li>
</ul>
<p>It is often enough to specify general defaults as widgets are rarely expected to behave differently with respect to size depending on the context but it can be useful in some cases.</p>
<p>Below we modify the sizing policy of gio via the <code>sizingPolicy</code> argument of the <code>createWidget</code> function. The function <code>htmlwidgets::sizingPolicy</code> has many arguments, we set the default width to 100% to ensure the visualisation fills its container entirely regardless of where it is rendered. We also remove all padding by setting it to 0 and set <code>browser.fill</code> to <code>TRUE</code> so it automatically resizes the visualisation to fit the entire browser page.</p>
<div class="sourceCode" id="cb164"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb164-1"><a href="advanced-topics.html#cb164-1"></a><span class="co"># create widget</span></span>
<span id="cb164-2"><a href="advanced-topics.html#cb164-2"></a>htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb164-3"><a href="advanced-topics.html#cb164-3"></a>  <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb164-4"><a href="advanced-topics.html#cb164-4"></a>  x,</span>
<span id="cb164-5"><a href="advanced-topics.html#cb164-5"></a>  <span class="dt">width =</span> width,</span>
<span id="cb164-6"><a href="advanced-topics.html#cb164-6"></a>  <span class="dt">height =</span> height,</span>
<span id="cb164-7"><a href="advanced-topics.html#cb164-7"></a>  <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb164-8"><a href="advanced-topics.html#cb164-8"></a>  <span class="dt">elementId =</span> elementId,</span>
<span id="cb164-9"><a href="advanced-topics.html#cb164-9"></a>  <span class="dt">sizingPolicy =</span> htmlwidgets<span class="op">::</span><span class="kw">sizingPolicy</span>(</span>
<span id="cb164-10"><a href="advanced-topics.html#cb164-10"></a>    <span class="dt">defaultWidth =</span> <span class="st">&quot;100%&quot;</span>,</span>
<span id="cb164-11"><a href="advanced-topics.html#cb164-11"></a>    <span class="dt">padding =</span> <span class="dv">0</span>,</span>
<span id="cb164-12"><a href="advanced-topics.html#cb164-12"></a>    <span class="dt">browser.fill =</span> <span class="ot">TRUE</span></span>
<span id="cb164-13"><a href="advanced-topics.html#cb164-13"></a>  )</span>
<span id="cb164-14"><a href="advanced-topics.html#cb164-14"></a>)</span></code></pre></div>
<div class="figure">
<img src="images/gio-fit.png" alt="" />
<p class="caption">Gio with sizing policy</p>
</div>
</div>
</div>
<div id="resizing" class="section level2" number="8.2">
<h2><span class="header-section-number">8.2</span> Resizing</h2>
<p>In the first widget built in this book (<code>playground</code>), when we deconstructed the JavaScript <code>factory</code> function but omitted the <code>resize</code> function. The <code>resize</code> function does what it says on the tin: it is called when the widget is resized. What this function will contain entirely depends on the JavaScript library one is working with. Some are very easy to resize other less so, that is for the developer to discover in the documentation of the library. Some libraries, like gio, do not even require using a resizing function and handle that automatically under the hood; resize the width of the RStudio viewer or web browser and gio.js resizes too. This said, there is a function to force resize gio, though it is not in the official documentation it can be found in the source code: <code>resizeUpdate</code> is a method of the controller and does not take any argument.</p>
<div class="sourceCode" id="cb165"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb165-1"><a href="advanced-topics.html#cb165-1"></a><span class="op">...</span></span>
<span id="cb165-2"><a href="advanced-topics.html#cb165-2"></a>resize<span class="op">:</span> <span class="kw">function</span>(width<span class="op">,</span> height) {</span>
<span id="cb165-3"><a href="advanced-topics.html#cb165-3"></a>  controller<span class="op">.</span><span class="fu">resizeUpdate</span>()<span class="op">;</span></span>
<span id="cb165-4"><a href="advanced-topics.html#cb165-4"></a>}</span>
<span id="cb165-5"><a href="advanced-topics.html#cb165-5"></a><span class="op">...</span></span></code></pre></div>
<div class="figure">
<img src="images/gio-small.png" alt="" />
<p class="caption">Gio resized</p>
</div>
<p>To give the reader a better idea of what these tend to look like below are the ways plotly, highcharts, and chart.js do it.</p>
<p><strong>Plotly</strong></p>
<div class="sourceCode" id="cb166"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb166-1"><a href="advanced-topics.html#cb166-1"></a>Plotly<span class="op">.</span><span class="fu">relayout</span>(<span class="st">&#39;chartid&#39;</span><span class="op">,</span> {<span class="dt">width</span><span class="op">:</span> width<span class="op">,</span> <span class="dt">height</span><span class="op">:</span> height})<span class="op">;</span></span></code></pre></div>
<p><strong>Highcharts</strong></p>
<div class="sourceCode" id="cb167"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb167-1"><a href="advanced-topics.html#cb167-1"></a>chart<span class="op">.</span><span class="fu">setSize</span>(width<span class="op">,</span> height)<span class="op">;</span></span></code></pre></div>
<p><strong>Chart.js</strong></p>
<div class="sourceCode" id="cb168"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb168-1"><a href="advanced-topics.html#cb168-1"></a>chart<span class="op">.</span><span class="fu">resize</span>()<span class="op">;</span></span></code></pre></div>
<p>Note that the <code>width</code> and <code>height</code> used in the functions above are obtained from the <code>resize</code> function itself (see arguments).</p>
<p>That is one of the reasons for ensuring the instance of the visualisation (<code>controller</code> in this case) is shared (declared in <code>factory</code>), if declared in the <code>renderValue</code> function then the <code>resize</code> function cannot access that object and thus cannot run the function required to resize the widget.</p>
</div>
<div id="pre-render-hooks-security" class="section level2" number="8.3">
<h2><span class="header-section-number">8.3</span> Pre Render Hooks &amp; Security</h2>
<p>The <code>createWidget</code> function also comes with a <code>preRenderHook</code> argument which accepts a function that is run just prior to the rendering, this function should accept the entire widget object as input, and should return a modified widget object. This was not used in any of the widgets previously built but is extremely useful. It can be used to make checks on the object to ensure all is correct, or remove variables that should only be used internally, and much more.</p>
<p>Currently, <code>gio</code> takes the data frame <code>data</code> and serialises it in its entirety which will cause security concerns as all the data used in the widget is visible in the source code of the output. What if the data used for the visualisation contained an additional column with sensitive information? We ought to ensure gio only serialises the data necessary to produce the visualisation.</p>
<div class="sourceCode" id="cb169"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb169-1"><a href="advanced-topics.html#cb169-1"></a><span class="co"># add a variable that should not be shared</span></span>
<span id="cb169-2"><a href="advanced-topics.html#cb169-2"></a>arcs<span class="op">$</span>secret_id &lt;-<span class="st"> </span><span class="dv">1</span><span class="op">:</span><span class="dv">2</span></span></code></pre></div>
<p>We create a <code>render_gio</code> function which accepts the entire widget, filters only the column necessary from the data and returns the widget. This function is then passed to the argument <code>preRenderHook</code> of the <code>htmlwidgets::createWidget</code> call. This way, only the columns <code>e</code>, <code>v</code>, and <code>i</code> of the data are kept thus the <code>secret_id</code> column will not be exposed publicly.</p>
<div class="sourceCode" id="cb170"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb170-1"><a href="advanced-topics.html#cb170-1"></a><span class="co"># preRenderHook function</span></span>
<span id="cb170-2"><a href="advanced-topics.html#cb170-2"></a>render_gio &lt;-<span class="st"> </span><span class="cf">function</span>(g){</span>
<span id="cb170-3"><a href="advanced-topics.html#cb170-3"></a>  <span class="co"># only keep relevant variables</span></span>
<span id="cb170-4"><a href="advanced-topics.html#cb170-4"></a>  g<span class="op">$</span>x<span class="op">$</span>data &lt;-<span class="st"> </span>g<span class="op">$</span>x<span class="op">$</span>data[,<span class="kw">c</span>(<span class="st">&quot;e&quot;</span>, <span class="st">&quot;v&quot;</span>, <span class="st">&quot;i&quot;</span>)]</span>
<span id="cb170-5"><a href="advanced-topics.html#cb170-5"></a>  <span class="kw">return</span>(g)</span>
<span id="cb170-6"><a href="advanced-topics.html#cb170-6"></a>}</span>
<span id="cb170-7"><a href="advanced-topics.html#cb170-7"></a></span>
<span id="cb170-8"><a href="advanced-topics.html#cb170-8"></a><span class="co"># create widget</span></span>
<span id="cb170-9"><a href="advanced-topics.html#cb170-9"></a>htmlwidgets<span class="op">::</span><span class="kw">createWidget</span>(</span>
<span id="cb170-10"><a href="advanced-topics.html#cb170-10"></a>  <span class="dt">name =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb170-11"><a href="advanced-topics.html#cb170-11"></a>  x,</span>
<span id="cb170-12"><a href="advanced-topics.html#cb170-12"></a>  <span class="dt">width =</span> width,</span>
<span id="cb170-13"><a href="advanced-topics.html#cb170-13"></a>  <span class="dt">height =</span> height,</span>
<span id="cb170-14"><a href="advanced-topics.html#cb170-14"></a>  <span class="dt">package =</span> <span class="st">&#39;gio&#39;</span>,</span>
<span id="cb170-15"><a href="advanced-topics.html#cb170-15"></a>  <span class="dt">elementId =</span> elementId,</span>
<span id="cb170-16"><a href="advanced-topics.html#cb170-16"></a>  <span class="dt">sizingPolicy =</span> htmlwidgets<span class="op">::</span><span class="kw">sizingPolicy</span>(</span>
<span id="cb170-17"><a href="advanced-topics.html#cb170-17"></a>    <span class="dt">defaultWidth =</span> <span class="st">&quot;100%&quot;</span>,</span>
<span id="cb170-18"><a href="advanced-topics.html#cb170-18"></a>    <span class="dt">padding =</span> <span class="dv">0</span>,</span>
<span id="cb170-19"><a href="advanced-topics.html#cb170-19"></a>    <span class="dt">browser.fill =</span> <span class="ot">TRUE</span></span>
<span id="cb170-20"><a href="advanced-topics.html#cb170-20"></a>  ),</span>
<span id="cb170-21"><a href="advanced-topics.html#cb170-21"></a>  <span class="dt">preRenderHook =</span> render_gio <span class="co"># pass renderer</span></span>
<span id="cb170-22"><a href="advanced-topics.html#cb170-22"></a>)</span></code></pre></div>
<p>Moreover, security aside, this can also improve performances as only the data relevant to the visualisation is serialised and subsequently loaded by the client. Without the modification above, were one to use <code>gio</code> on a dataset with 100 columns all would have been serialised, thereby greatly impacting performances both of the R process rendering the output and the web browser viewing the visualisation.</p>
</div>
<div id="javascript-code" class="section level2" number="8.4">
<h2><span class="header-section-number">8.4</span> JavaScript Code</h2>
<p>As mentioned in a previous chapter JavaScript code cannot be serialised to JSON.</p>
<div class="sourceCode" id="cb171"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb171-1"><a href="advanced-topics.html#cb171-1"></a><span class="co"># serialised as string</span></span>
<span id="cb171-2"><a href="advanced-topics.html#cb171-2"></a>jsonlite<span class="op">::</span><span class="kw">toJSON</span>(<span class="st">&quot;var x = 3;&quot;</span>)</span></code></pre></div>
<pre><code>## [&quot;var x = 3;&quot;]</code></pre>
<p>Nonetheless, it is doable with htmlwidgets’ serialiser (and only that one). The function <code>htmlwidgets::JS</code> can be used to mark a character vector so that it will be treated as JavaScript code when evaluated in the browser.</p>
<div class="sourceCode" id="cb173"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb173-1"><a href="advanced-topics.html#cb173-1"></a>htmlwidgets<span class="op">::</span><span class="kw">JS</span>(<span class="st">&quot;var x = 3;&quot;</span>)  </span></code></pre></div>
<pre><code>## [1] &quot;var x = 3;&quot;
## attr(,&quot;class&quot;)
## [1] &quot;JS_EVAL&quot;</code></pre>
<p>This can be useful where the library requires the use of callback functions for instance.</p>
<div class="rmdnote">
<p>
Replacing the serialiser will break this feature.
</p>
</div>
</div>
<div id="prepend-append-content" class="section level2" number="8.5">
<h2><span class="header-section-number">8.5</span> Prepend &amp; Append Content</h2>
<p>There is the ability to append of prepend HTML content to the widget (shiny, htmltools tags, or a list of those). For instance, we could use <code>htmlwidgets::prependContent</code> to allow displaying a title to the visualisation as shown below.</p>
<div class="sourceCode" id="cb175"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb175-1"><a href="advanced-topics.html#cb175-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb175-2"><a href="advanced-topics.html#cb175-2"></a>gio_title &lt;-<span class="st"> </span><span class="cf">function</span>(g, title){</span>
<span id="cb175-3"><a href="advanced-topics.html#cb175-3"></a>  title &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">h3</span>(title)</span>
<span id="cb175-4"><a href="advanced-topics.html#cb175-4"></a>  htmlwidgets<span class="op">::</span><span class="kw">prependContent</span>(g, title)</span>
<span id="cb175-5"><a href="advanced-topics.html#cb175-5"></a>}</span></code></pre></div>
<div class="sourceCode" id="cb176"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb176-1"><a href="advanced-topics.html#cb176-1"></a><span class="kw">gio</span>(arcs) <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb176-2"><a href="advanced-topics.html#cb176-2"></a><span class="st">  </span><span class="kw">gio_title</span>(<span class="st">&quot;Gio.js htmlwidget!&quot;</span>)</span></code></pre></div>
<div class="figure">
<img src="images/gio-title.png" alt="" />
<p class="caption">Gio output with a title</p>
</div>
<p>While the <code>prependContent</code> function places the content above the visualisation, the <code>appendContent</code> function places it below, as they accept any valid htmltools or shiny tag they can also be used for conditional CSS styling for instance.</p>
<div class="rmdnote">
<p>
<code>prependContent</code> and <code>appendContent</code> do not work in shiny.
</p>
</div>
</div>
<div id="dependencies" class="section level2" number="8.6">
<h2><span class="header-section-number">8.6</span> Dependencies</h2>
<p>Thus far, this book has only covered one of two ways dependencies can be included in htmlwidgets. Though the one covered, using the <code>.yml</code> file, will likely be necessary for every widget it has one drawback: all dependencies listed in the file are always included with the output. Dependencies can greatly affect the load time of the output (be it a standalone visualisation, an R markdown document, or a shiny application) as these files may be large. Most large visualisation libraries will therefore allow to bundle those dependencies in separate files. For instance, ECharts.js provides a way to customise the bundle to only include dependencies for charts that one wants to draw (e.g.: bar chart, or boxplot), Highcharts also allows splitting dependencies so one can load those needed for maps, stock charts, and more, separately. It is thus good practice to do the same in widgets so only the required dependencies are loaded, e.g.: when the user produces a map, only the dependency for that map is loaded. It is used in the leaflet package to load map tiles for instance.</p>
<p>The Google Chrome network tab shows information on resources downloaded by the browser (including dependencies) including how long it takes. It is advisable to take a look at it to ensure no dependency drags load time.</p>
<div class="figure">
<img src="images/htmlwidgets-performances.png" alt="" />
<p class="caption">Google Chrome network tab</p>
</div>
<p>To demonstrate, we will add a function in gio to optionally include <a href="https://github.com/mrdoob/stats.js/">stats.js</a>, a JavaScript performance monitor which displays information such as the number of frames per second (FPS) rendered, or the number of milliseconds needed to render the visualisation. Gio.js natively supports stats.js but the dependency needs to be imported and that option needs to be enabled on the <code>controller</code> as shown in the <a href="https://giojs.org/html/docs/interfaceStats.html">documentation</a>.</p>
<div class="sourceCode" id="cb177"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb177-1"><a href="advanced-topics.html#cb177-1"></a><span class="co">// enable stats</span></span>
<span id="cb177-2"><a href="advanced-topics.html#cb177-2"></a>controller<span class="op">.</span><span class="fu">enableStats</span>()<span class="op">;</span></span></code></pre></div>
<p>In htmlwidgets those additional dependencies can be specified via the <code>dependencies</code> argument in the <code>htmlwidgets::createWidget</code> function, or they can be appended to the output of that function.</p>
<pre><code># create gio object
g &lt;- gio::gio(arcs)

is.null(g$dependencies)</code></pre>
<pre><code>[1] TRUE</code></pre>
<p>As shown above, the object created by <code>gio</code> includes dependencies, currently <code>NULL</code> as no such extra dependency is specified. One can therefore append those to that object in a fashion similar to what the <code>gio_style</code> function does.</p>
<p>From the root of the gio package we create a new directory for the stats.js dependency and download version <code>r17</code> from the CDN.</p>
<div class="sourceCode" id="cb180"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb180-1"><a href="advanced-topics.html#cb180-1"></a><span class="kw">dir.create</span>(<span class="st">&quot;htmlwidgets/stats&quot;</span>)</span>
<span id="cb180-2"><a href="advanced-topics.html#cb180-2"></a>url &lt;-<span class="st"> </span><span class="kw">paste0</span>(</span>
<span id="cb180-3"><a href="advanced-topics.html#cb180-3"></a>  <span class="st">&quot;https://cdnjs.cloudflare.com/ajax/libs/&quot;</span>,</span>
<span id="cb180-4"><a href="advanced-topics.html#cb180-4"></a>  <span class="st">&quot;stats.js/r17/Stats.min.js&quot;</span></span>
<span id="cb180-5"><a href="advanced-topics.html#cb180-5"></a>)</span>
<span id="cb180-6"><a href="advanced-topics.html#cb180-6"></a><span class="kw">download.file</span>(url, <span class="dt">destfile =</span> <span class="st">&quot;htmlwidgets/stats/stats.min.js&quot;</span>)</span></code></pre></div>
<p>First we use the <code>system.file</code> function to retrieve <em>the path to the directory</em> which contains the dependency (<code>stats.min.js</code>). It’s important that it is the path to the directory and not the file itself.</p>
<div class="sourceCode" id="cb181"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb181-1"><a href="advanced-topics.html#cb181-1"></a><span class="co"># stats.R</span></span>
<span id="cb181-2"><a href="advanced-topics.html#cb181-2"></a>gio_stats &lt;-<span class="st"> </span><span class="cf">function</span>(g){</span>
<span id="cb181-3"><a href="advanced-topics.html#cb181-3"></a></span>
<span id="cb181-4"><a href="advanced-topics.html#cb181-4"></a>  <span class="co"># create dependency</span></span>
<span id="cb181-5"><a href="advanced-topics.html#cb181-5"></a>  path &lt;-<span class="st"> </span><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/stats&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;gio&quot;</span>)</span>
<span id="cb181-6"><a href="advanced-topics.html#cb181-6"></a></span>
<span id="cb181-7"><a href="advanced-topics.html#cb181-7"></a>  <span class="kw">return</span>(g)</span>
<span id="cb181-8"><a href="advanced-topics.html#cb181-8"></a></span>
<span id="cb181-9"><a href="advanced-topics.html#cb181-9"></a>}</span></code></pre></div>
<p>Then we use the htmltools package to create a dependency, the <code>htmltools::htmlDependency</code> function returns an object of class <code>html_dependency</code> which htmlwidgets can understand and subsequently insert in the output. On the <code>src</code> parameter, since we reference a dependency from the filesystem we name the character string <code>file</code> but we could use the CDN (web hosted file) and name it <code>href</code> instead.</p>
<div class="sourceCode" id="cb182"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb182-1"><a href="advanced-topics.html#cb182-1"></a><span class="co"># stats.R</span></span>
<span id="cb182-2"><a href="advanced-topics.html#cb182-2"></a>gio_stats &lt;-<span class="st"> </span><span class="cf">function</span>(g){</span>
<span id="cb182-3"><a href="advanced-topics.html#cb182-3"></a></span>
<span id="cb182-4"><a href="advanced-topics.html#cb182-4"></a>  <span class="co"># create dependency</span></span>
<span id="cb182-5"><a href="advanced-topics.html#cb182-5"></a>  path &lt;-<span class="st"> </span><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/stats&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;gio&quot;</span>)</span>
<span id="cb182-6"><a href="advanced-topics.html#cb182-6"></a>  dep &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</span>
<span id="cb182-7"><a href="advanced-topics.html#cb182-7"></a>    <span class="dt">name =</span> <span class="st">&quot;stats&quot;</span>,</span>
<span id="cb182-8"><a href="advanced-topics.html#cb182-8"></a>    <span class="dt">version =</span> <span class="st">&quot;17&quot;</span>,</span>
<span id="cb182-9"><a href="advanced-topics.html#cb182-9"></a>    <span class="dt">src =</span> <span class="kw">c</span>(<span class="dt">file =</span> path),</span>
<span id="cb182-10"><a href="advanced-topics.html#cb182-10"></a>    <span class="dt">script =</span> <span class="st">&quot;stats.min.js&quot;</span></span>
<span id="cb182-11"><a href="advanced-topics.html#cb182-11"></a>  )</span>
<span id="cb182-12"><a href="advanced-topics.html#cb182-12"></a></span>
<span id="cb182-13"><a href="advanced-topics.html#cb182-13"></a>  <span class="kw">return</span>(g)</span>
<span id="cb182-14"><a href="advanced-topics.html#cb182-14"></a></span>
<span id="cb182-15"><a href="advanced-topics.html#cb182-15"></a>}</span></code></pre></div>
<p>The dependency then needs to be appended to the htmlwidgets object.</p>
<div class="sourceCode" id="cb183"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb183-1"><a href="advanced-topics.html#cb183-1"></a><span class="co"># stats.R</span></span>
<span id="cb183-2"><a href="advanced-topics.html#cb183-2"></a>gio_stats &lt;-<span class="st"> </span><span class="cf">function</span>(g){</span>
<span id="cb183-3"><a href="advanced-topics.html#cb183-3"></a></span>
<span id="cb183-4"><a href="advanced-topics.html#cb183-4"></a>  <span class="co"># create dependency</span></span>
<span id="cb183-5"><a href="advanced-topics.html#cb183-5"></a>  path &lt;-<span class="st"> </span><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/stats&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;gio&quot;</span>)</span>
<span id="cb183-6"><a href="advanced-topics.html#cb183-6"></a>  dep &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</span>
<span id="cb183-7"><a href="advanced-topics.html#cb183-7"></a>    <span class="dt">name =</span> <span class="st">&quot;stats&quot;</span>,</span>
<span id="cb183-8"><a href="advanced-topics.html#cb183-8"></a>    <span class="dt">version =</span> <span class="st">&quot;17&quot;</span>,</span>
<span id="cb183-9"><a href="advanced-topics.html#cb183-9"></a>    <span class="dt">src =</span> <span class="kw">c</span>(<span class="dt">file =</span> path),</span>
<span id="cb183-10"><a href="advanced-topics.html#cb183-10"></a>    <span class="dt">script =</span> <span class="st">&quot;stats.min.js&quot;</span></span>
<span id="cb183-11"><a href="advanced-topics.html#cb183-11"></a>  )</span>
<span id="cb183-12"><a href="advanced-topics.html#cb183-12"></a></span>
<span id="cb183-13"><a href="advanced-topics.html#cb183-13"></a>  <span class="co"># append dependency</span></span>
<span id="cb183-14"><a href="advanced-topics.html#cb183-14"></a>  g<span class="op">$</span>dependencies &lt;-<span class="st"> </span><span class="kw">append</span>(g<span class="op">$</span>dependencies, <span class="kw">list</span>(dep))</span>
<span id="cb183-15"><a href="advanced-topics.html#cb183-15"></a></span>
<span id="cb183-16"><a href="advanced-topics.html#cb183-16"></a>  <span class="kw">return</span>(g)</span>
<span id="cb183-17"><a href="advanced-topics.html#cb183-17"></a></span>
<span id="cb183-18"><a href="advanced-topics.html#cb183-18"></a>}</span></code></pre></div>
<p>Finally, we pass an additional variable in the list of options (<code>x</code>) which we will use JavaScript-side to check whether stats.js must be enabled.</p>
<div class="sourceCode" id="cb184"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb184-1"><a href="advanced-topics.html#cb184-1"></a><span class="co">#&#39; @export</span></span>
<span id="cb184-2"><a href="advanced-topics.html#cb184-2"></a>gio_stats &lt;-<span class="st"> </span><span class="cf">function</span>(g){</span>
<span id="cb184-3"><a href="advanced-topics.html#cb184-3"></a></span>
<span id="cb184-4"><a href="advanced-topics.html#cb184-4"></a>  <span class="co"># create dependency</span></span>
<span id="cb184-5"><a href="advanced-topics.html#cb184-5"></a>  path &lt;-<span class="st"> </span><span class="kw">system.file</span>(<span class="st">&quot;htmlwidgets/stats&quot;</span>, <span class="dt">package =</span> <span class="st">&quot;gio&quot;</span>)</span>
<span id="cb184-6"><a href="advanced-topics.html#cb184-6"></a>  dep &lt;-<span class="st"> </span>htmltools<span class="op">::</span><span class="kw">htmlDependency</span>(</span>
<span id="cb184-7"><a href="advanced-topics.html#cb184-7"></a>    <span class="dt">name =</span> <span class="st">&quot;stats&quot;</span>,</span>
<span id="cb184-8"><a href="advanced-topics.html#cb184-8"></a>    <span class="dt">version =</span> <span class="st">&quot;17&quot;</span>,</span>
<span id="cb184-9"><a href="advanced-topics.html#cb184-9"></a>    <span class="dt">src =</span> <span class="kw">c</span>(<span class="dt">file =</span> path),</span>
<span id="cb184-10"><a href="advanced-topics.html#cb184-10"></a>    <span class="dt">script =</span> <span class="st">&quot;stats.min.js&quot;</span></span>
<span id="cb184-11"><a href="advanced-topics.html#cb184-11"></a>  )</span>
<span id="cb184-12"><a href="advanced-topics.html#cb184-12"></a></span>
<span id="cb184-13"><a href="advanced-topics.html#cb184-13"></a>  <span class="co"># append dependency to gio.js</span></span>
<span id="cb184-14"><a href="advanced-topics.html#cb184-14"></a>  g<span class="op">$</span>dependencies &lt;-<span class="st"> </span><span class="kw">append</span>(g<span class="op">$</span>dependencies, <span class="kw">list</span>(dep))</span>
<span id="cb184-15"><a href="advanced-topics.html#cb184-15"></a></span>
<span id="cb184-16"><a href="advanced-topics.html#cb184-16"></a>  <span class="co"># add stats variable</span></span>
<span id="cb184-17"><a href="advanced-topics.html#cb184-17"></a>  g<span class="op">$</span>x<span class="op">$</span>stats &lt;-<span class="st"> </span><span class="ot">TRUE</span></span>
<span id="cb184-18"><a href="advanced-topics.html#cb184-18"></a></span>
<span id="cb184-19"><a href="advanced-topics.html#cb184-19"></a>  <span class="kw">return</span>(g)</span>
<span id="cb184-20"><a href="advanced-topics.html#cb184-20"></a>}</span></code></pre></div>
<p>Then it’s a matter of using the <code>stats</code> variable added to <code>x</code> in the JavaScript <code>renderValue</code> function to determine whether the stats feature should be enabled.</p>
<div class="sourceCode" id="cb185"><pre class="sourceCode js"><code class="sourceCode javascript"><span id="cb185-1"><a href="advanced-topics.html#cb185-1"></a><span class="co">// gio.js</span></span>
<span id="cb185-2"><a href="advanced-topics.html#cb185-2"></a><span class="cf">if</span>(x<span class="op">.</span><span class="at">stats</span>)</span>
<span id="cb185-3"><a href="advanced-topics.html#cb185-3"></a>  controller<span class="op">.</span><span class="fu">enableStats</span>()<span class="op">;</span></span>
<span id="cb185-4"><a href="advanced-topics.html#cb185-4"></a></span>
<span id="cb185-5"><a href="advanced-topics.html#cb185-5"></a>controller<span class="op">.</span><span class="fu">init</span>()<span class="op">;</span></span></code></pre></div>
<p>Then the package can be documented to export the newly created function and loaded in the environment to test the feature.</p>
<div class="sourceCode" id="cb186"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb186-1"><a href="advanced-topics.html#cb186-1"></a><span class="co"># create gio object</span></span>
<span id="cb186-2"><a href="advanced-topics.html#cb186-2"></a>arcs <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb186-3"><a href="advanced-topics.html#cb186-3"></a><span class="st">  </span><span class="kw">gio</span>() <span class="op">%&gt;%</span><span class="st"> </span></span>
<span id="cb186-4"><a href="advanced-topics.html#cb186-4"></a><span class="st">  </span><span class="kw">gio_stats</span>()</span></code></pre></div>
<div class="figure">
<img src="images/stats.png" alt="" />
<p class="caption">Gio with stats output</p>
</div>
<p>In brief, it is better to only place the hard dependencies in the <code>.yml</code> file; dependencies that are absolutely necessary to producing the visualisation and use dynamic dependencies where ever possible. Perhaps one can think of it as the difference between <code>Imports</code> and <code>Suggests</code> in an R package <code>DESCRIPTION</code> file.</p>
</div>
<div id="compatibility" class="section level2" number="8.7">
<h2><span class="header-section-number">8.7</span> Compatibility</h2>
<p>One issue that might arise is that of compatibility between widgets. What if someone else builds another htmlwidget for gio.js which uses a different version of the library and that a user decides to use both packages in a shiny app or R markdown document? Something is likely to fail as two different version of gio.js are imported and that one overrides the other. For instance, the package echarts4r <span class="citation">(Coene <a href="#ref-R-echarts4r" role="doc-biblioref">2020</a><a href="#ref-R-echarts4r" role="doc-biblioref">a</a>)</span> allows working with leaflet but including the dependencies could clash with the leaflet package itself, therefore it uses the dependencies from the leaflet package instead.</p>
<p>The htmlwidgets package comes with a function to extract the dependencies from a widget, so they can be reused in another. The function <code>htmlwidgets::getDependency</code> returns a list of objects of class <code>html_dependency</code> which can therefore be used in other widgets as demonstrated in the previous section.</p>
<div class="sourceCode" id="cb187"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb187-1"><a href="advanced-topics.html#cb187-1"></a><span class="co"># get dependencies of the gio package</span></span>
<span id="cb187-2"><a href="advanced-topics.html#cb187-2"></a>htmlwidgets<span class="op">::</span><span class="kw">getDependency</span>(<span class="st">&quot;gio&quot;</span>)[<span class="dv">2</span><span class="op">:</span><span class="dv">3</span>]</span></code></pre></div>
<pre><code>## [[1]]
## List of 10
##  $ name      : chr &quot;three&quot;
##  $ version   : chr &quot;110&quot;
##  $ src       :List of 1
##   ..$ file: chr &quot;/Library/Frameworks/R.framework/Versions/4.0/Resources/library/gio/htmlwidgets/three&quot;
##  $ meta      : NULL
##  $ script    : chr &quot;three.min.js&quot;
##  $ stylesheet: NULL
##  $ head      : NULL
##  $ attachment: NULL
##  $ package   : NULL
##  $ all_files : logi TRUE
##  - attr(*, &quot;class&quot;)= chr &quot;html_dependency&quot;
## 
## [[2]]
## List of 10
##  $ name      : chr &quot;gio&quot;
##  $ version   : chr &quot;2&quot;
##  $ src       :List of 1
##   ..$ file: chr &quot;/Library/Frameworks/R.framework/Versions/4.0/Resources/library/gio/htmlwidgets/gio&quot;
##  $ meta      : NULL
##  $ script    : chr &quot;gio.min.js&quot;
##  $ stylesheet: NULL
##  $ head      : NULL
##  $ attachment: NULL
##  $ package   : NULL
##  $ all_files : logi TRUE
##  - attr(*, &quot;class&quot;)= chr &quot;html_dependency&quot;</code></pre>
</div>
<div id="unit-tests" class="section level2" number="8.8">
<h2><span class="header-section-number">8.8</span> Unit Tests</h2>
<p>The best way to write unit tests for htmlwidgets is to test the object created by <code>htmlwidgets::createWidget</code>. Below we provide an example using testthat<span class="citation">(Wickham <a href="#ref-R-testthat" role="doc-biblioref">2020</a>)</span>, running <code>expect*</code> functions on the output of <code>gio</code>.</p>
<div class="sourceCode" id="cb189"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb189-1"><a href="advanced-topics.html#cb189-1"></a><span class="kw">library</span>(gio)</span>
<span id="cb189-2"><a href="advanced-topics.html#cb189-2"></a><span class="kw">library</span>(testthat)</span>
<span id="cb189-3"><a href="advanced-topics.html#cb189-3"></a></span>
<span id="cb189-4"><a href="advanced-topics.html#cb189-4"></a><span class="kw">test_that</span>(<span class="st">&quot;gio has correct data&quot;</span>, {</span>
<span id="cb189-5"><a href="advanced-topics.html#cb189-5"></a>  g &lt;-<span class="st"> </span><span class="kw">gio</span>(arcs)</span>
<span id="cb189-6"><a href="advanced-topics.html#cb189-6"></a></span>
<span id="cb189-7"><a href="advanced-topics.html#cb189-7"></a>  <span class="co"># internally stored as data.frame</span></span>
<span id="cb189-8"><a href="advanced-topics.html#cb189-8"></a>  <span class="kw">expect_is</span>(g<span class="op">$</span>x<span class="op">$</span>data, <span class="st">&quot;data.frame&quot;</span>)</span>
<span id="cb189-9"><a href="advanced-topics.html#cb189-9"></a></span>
<span id="cb189-10"><a href="advanced-topics.html#cb189-10"></a>  <span class="co"># gio does not work without data</span></span>
<span id="cb189-11"><a href="advanced-topics.html#cb189-11"></a>  <span class="kw">expect_error</span>(<span class="kw">gio</span>())</span>
<span id="cb189-12"><a href="advanced-topics.html#cb189-12"></a>})</span></code></pre></div>
</div>
<div id="performances" class="section level2" number="8.9">
<h2><span class="header-section-number">8.9</span> Performances</h2>
<p>A few hints have already been given to ensure one does not drain the browser, consider assessing the performances of the widget as it is being built. Always try and imagine what happens under the hood of the htmlwidget as you build it, it often reveals potential bottlenecks and solutions.</p>
<p>Remember that data passed to <code>htmlwidgets::createWidget</code> is 1) loaded into R, 2) serialised to JSON, 3) embedded into the HTML output, 4) read back in with JavaScript, which adds some overhead considering it might be read into JavaScript directly. This will not be a problem for most visualisations but might become one when that data is large. Indeed, there are sometimes more efficient ways to load data into web browsers where it is needed for the visualisation.</p>
<p>Consider for instance geographic features (topoJSON and GeoJSON), why load them into R if it is to then re-serialise it to JSON?</p>
<p>Also keep the previous remark in mind when repeatedly serialising identical data objects, GeoJSON is again a good example. A map used twice or more should only be serialised once or better not at all. Consider providing other ways to for the developer to make potentially large data files accessible to the browser.</p>
<p>Below is an example of function that could be used within R markdown or shiny UI to load data in the front-end and bypass serialisation. Additionally the function makes use of AJAX (Asynchronous JavaScript And XML) to asynchronously load the data, thereby further reducing load time.</p>
<div class="sourceCode" id="cb190"><pre class="sourceCode r"><code class="sourceCode r"><span id="cb190-1"><a href="advanced-topics.html#cb190-1"></a><span class="co"># this would placed in the shiny UI</span></span>
<span id="cb190-2"><a href="advanced-topics.html#cb190-2"></a>load_json_from_ui &lt;-<span class="st"> </span><span class="cf">function</span>(path_to_json){</span>
<span id="cb190-3"><a href="advanced-topics.html#cb190-3"></a>  script &lt;-<span class="st"> </span><span class="kw">paste0</span>(<span class="st">&quot;</span></span>
<span id="cb190-4"><a href="advanced-topics.html#cb190-4"></a><span class="st">    $.ajax({ </span></span>
<span id="cb190-5"><a href="advanced-topics.html#cb190-5"></a><span class="st">        url: &#39;&quot;</span>, path_to_json, <span class="st">&quot;&#39;, </span></span>
<span id="cb190-6"><a href="advanced-topics.html#cb190-6"></a><span class="st">        dataType: &#39;json&#39;, </span></span>
<span id="cb190-7"><a href="advanced-topics.html#cb190-7"></a><span class="st">        async: true,</span></span>
<span id="cb190-8"><a href="advanced-topics.html#cb190-8"></a><span class="st">        success: function(data){ </span></span>
<span id="cb190-9"><a href="advanced-topics.html#cb190-9"></a><span class="st">          console.log(data);</span></span>
<span id="cb190-10"><a href="advanced-topics.html#cb190-10"></a><span class="st">          window.globalData = data;</span></span>
<span id="cb190-11"><a href="advanced-topics.html#cb190-11"></a><span class="st">        } </span></span>
<span id="cb190-12"><a href="advanced-topics.html#cb190-12"></a><span class="st">      });&quot;</span></span>
<span id="cb190-13"><a href="advanced-topics.html#cb190-13"></a>    )</span>
<span id="cb190-14"><a href="advanced-topics.html#cb190-14"></a>  shiny<span class="op">::</span>tags<span class="op">$</span><span class="kw">script</span>(</span>
<span id="cb190-15"><a href="advanced-topics.html#cb190-15"></a>    script</span>
<span id="cb190-16"><a href="advanced-topics.html#cb190-16"></a>  )</span>
<span id="cb190-17"><a href="advanced-topics.html#cb190-17"></a>}</span></code></pre></div>
<p>Using the above the data loaded would be accessible from the htmlwidgets JavaScript (e.g.: <code>gio.js</code>) with <code>window.globalData</code>. The <code>window</code> object is akin to the <code>document</code> object, while the latter pertains to the Document Object Model (DOM) and represents the page, the former pertains to the Browser Object Model (BOM) and represents the browser window. While <code>var x;</code> will only be accessible within the script where it is declared, <code>window.x</code> will be accessible anywhere.</p>
<p>Note this means the data is read from the web browser and therefore the data must be accessible to the web browser, the <code>path_to_json</code> must thus be a served static file, e.g.: <code>www</code> directory in shiny.</p>

</div>
</div>
<h3>References</h3>
<div id="refs" class="references">
<div id="ref-R-echarts4r">
<p>Coene, John. 2020a. <em>Echarts4r: Create Interactive Graphs with ’Echarts Javascript’ Version 4</em>. <a href="http://echarts4r.john-coene.com/">http://echarts4r.john-coene.com/</a>.</p>
</div>
<div id="ref-R-testthat">
<p>Wickham, Hadley. 2020. <em>Testthat: Unit Testing for R</em>. <a href="https://CRAN.R-project.org/package=testthat">https://CRAN.R-project.org/package=testthat</a>.</p>
</div>
</div>
            </section>

          </div>
        </div>
      </div>
<a href="the-full-monty.html" class="navigation navigation-prev " aria-label="Previous page"><i class="fa fa-angle-left"></i></a>
<a href="linking-widgets.html" class="navigation navigation-next " aria-label="Next page"><i class="fa fa-angle-right"></i></a>
    </div>
  </div>
<script src="libs/gitbook/js/app.min.js"></script>
<script src="libs/gitbook/js/lunr.js"></script>
<script src="libs/gitbook/js/clipboard.min.js"></script>
<script src="libs/gitbook/js/plugin-search.js"></script>
<script src="libs/gitbook/js/plugin-sharing.js"></script>
<script src="libs/gitbook/js/plugin-fontsettings.js"></script>
<script src="libs/gitbook/js/plugin-bookdown.js"></script>
<script src="libs/gitbook/js/jquery.highlight.js"></script>
<script src="libs/gitbook/js/plugin-clipboard.js"></script>
<script>
gitbook.require(["gitbook"], function(gitbook) {
gitbook.start({
"sharing": {
"github": true,
"facebook": false,
"twitter": false,
"linkedin": false,
"weibo": false,
"instapaper": false,
"vk": false,
"all": {}
},
"fontsettings": {
"theme": "white",
"family": "sans",
"size": 2
},
"edit": {
"link": "https://github.com/JohnCoene/javascript-for-r/edit/master/3-25-htmlwidgets-advanced.Rmd",
"text": "Edit"
},
"history": {
"link": null,
"text": null
},
"view": {
"link": null,
"text": null
},
"download": {},
"toc": {
"collapse": "section"
}
});
});
</script>

</body>

</html>
